package com.codeoss.framework.webide.app.service.impl;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.codeoss.framework.context.YunContext;
import com.codeoss.framework.util.IOUtil;
import com.codeoss.framework.webide.app.service.IAppDataHandler;
import com.codeoss.framework.webide.app.service.store.IAppDataHandlerStore;
import com.codeoss.module.ir.model.IrApplication;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;

@Service
public class AppImportManager {
	@Autowired
	private ObjectMapper objectMapper;
	@Autowired
	private IAppDataHandlerStore appDataHandlerStore;
	@Value("${framework.base-path}")
	private String basePath;
	
	@Transactional
	public void importApp(YunContext yunContext,InputStream is) {
		String folderName = UUID.randomUUID().toString();
		File folder = new File(basePath + File.separator + "code" + File.separator + folderName);
		folder.mkdirs();
		ZipInputStream zin = new ZipInputStream(is);
		try {
			ZipEntry entry;
			while ((entry = zin.getNextEntry()) != null) {
				byte b[] = new byte[1024];
				String filename = entry.getName();
				File file = new File(folder, filename);
				FileOutputStream fos = new FileOutputStream(file);
				int count;
				while ((count = zin.read(b)) != -1) {
					fos.write(b, 0, count);
				}
				fos.close();
			}
		}catch(Exception e) {
			throw new RuntimeException(e);
		} finally {
			try {
				zin.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				throw new RuntimeException(e);
			}
			IOUtil.closeInputStream(is);
		}
		
		InputStream appconfigIs=this.getClass().getClassLoader().getResourceAsStream("com/codeoss/framework/webide/app/service/impl/appconfig.json");
		JsonNode appJsonNode=null;
		try {
			 appJsonNode=objectMapper.readTree(appconfigIs);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			throw new RuntimeException(e);
		}finally {
			IOUtil.closeInputStream(appconfigIs);
		}
		
		yunContext.setAttribute("__folder__", folder);
		
		Map<String,List<String>> tableFileListMap=new HashMap<String,List<String>>();
		File configFile = new File(folder, "app_config.cfg");
		BufferedReader br=null;
		IrApplication irApplication=new IrApplication();
		try {
			br = new BufferedReader(new FileReader(configFile));
			String line = null;
			while ((line = br.readLine()) != null) {
				String contentArray[] = line.split("=");
				String tableName = contentArray[0];
				if("appcode".equals(tableName)) {
					irApplication.setCode(contentArray[1]);
				}else if("appname".equals(tableName)) {
					irApplication.setName(contentArray[1]);
				}else if("module_type_list".equals(tableName)) {
					irApplication.setModuleTypeList(contentArray[1]);
				}else {
					List<String> fileList=tableFileListMap.get(tableName);
					if(fileList==null) {
						fileList=new ArrayList<String>();
						tableFileListMap.put(tableName, fileList);
					}
					fileList.add(contentArray[1]);
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			throw new RuntimeException(e);
		}finally {
			try {
				br.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		ArrayNode tableListArrayNode=(ArrayNode)appJsonNode.get("tableList");
		for(int i=0;i<tableListArrayNode.size();i++) {
			JsonNode jsonNode=tableListArrayNode.get(i);
			String table=jsonNode.get("table").asText();
			IAppDataHandler appDataHandler=appDataHandlerStore.getAppDataHandlerByTable(yunContext, table);
			List<String> filenameList=tableFileListMap.get(table);
			try {
				appDataHandler.dataImport(yunContext, irApplication, table, filenameList);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				throw new RuntimeException(e);
			}
		}
	}
}
